﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Pavilion;

namespace Pavilion.GameTools
{
    public class CameraTool : GameToolBase
    {
        public string FocusGameItem { get { return focusGameItem; } set { focusGameItem = value; UpdateCurrentPhysicalData(); } }

        private static Dictionary<string, Action<CameraTool, object>> dataExecutionDictionary;
        static private Rectangle focusBounds;
        static private string focusGameItem;
        static PhysicalData physicalData;

        public CameraTool(GameItem parentGameItem) : base(parentGameItem)
        {
            LoadDataExecution();
        }

        public override void Dispose()
        {
            isLoaded = false;
            FocusGameItem = null;

            base.Dispose();
        }

        private static bool isLoaded;
        public override void Load()
        {
            if (!isLoaded)
            {
                isLoaded = true;
                focusBounds = new Rectangle(GameEngine.WindowWidth / 2 - 150, GameEngine.WindowHeight / 2 - 150, 250, 250);
            }
        }

        private void LoadDataExecution()
        {
            if (dataExecutionDictionary != null)
                return;

            dataExecutionDictionary = new Dictionary<string, Action<CameraTool, object>>();
            dataExecutionDictionary.Add("FocusGameItem", (cameraTool, value) => cameraTool.FocusGameItem = (string)value);
        }

        public override void UpdateProperty(string propertyName, object propertyValue)
        {
            dataExecutionDictionary[propertyName].Invoke(this, propertyValue);
        }

        private void UpdateScreen()
        {
            float xDistance = 0f;
            float yDistance = 0f;

            if (physicalData.Position.X < focusBounds.Left)
                xDistance = (int)physicalData.Position.X - focusBounds.Left;
            else if (physicalData.Position.X > focusBounds.Right)
                xDistance = (int)physicalData.Position.X - focusBounds.Right;

            if (physicalData.Position.Y < focusBounds.Top)
                yDistance = (int)physicalData.Position.Y - focusBounds.Top;
            else if (physicalData.Position.Y > focusBounds.Bottom)
                yDistance = (int)physicalData.Position.Y - focusBounds.Bottom;

            MoveScreen(xDistance, yDistance);
        }

        private void MoveScreen(float xDistance, float yDistance)
        {
            focusBounds.X += (int)xDistance;
            focusBounds.Y += (int)yDistance;

            DrawManager.Instance.FocusStartingPoint.X += xDistance;
            DrawManager.Instance.FocusStartingPoint.Y += yDistance;
        }

        private void UpdateCurrentPhysicalData()
        {
            if (physicalData != null)
                physicalData.PositionChanged -= PhysicalData_PositionChanged;
            try
            {
                physicalData = PhysicalTypeTool.PhysicalDataCollection[FocusGameItem];
                physicalData.PositionChanged += PhysicalData_PositionChanged;
                UpdateScreen();
            }
            catch { physicalData = null; }
        }

        private void PhysicalData_PositionChanged(PhysicalData physicalData)
        {
            UpdateScreen();
        }
    }
}
